#include "ImgCutter.h"
#include "Encryptor.h"

#include <QMapIterator>

#include <QDebug>

ImgCutter *imgCutter = new ImgCutter();

ImgCutter::ImgCutter():
    log_global("./data/log_global"),
    log_progress("./data/log_progress")
{
    name_filters << "*.jpg";

    rect_map = NULL;
    rename_style = Encoded;
}

void ImgCutter::setRectMap(const QMap<QString, QRect> *map){
    rect_map = map;
}

void ImgCutter::setRenameStyle(RenameStyle style){
    rename_style = style;
}

bool ImgCutter::setInputDirectory(QString dir){
    input_directory.setPath(dir);

    if(input_directory.isReadable()){
        image_list = input_directory.entryList(name_filters);
        return true;
    }else{
        return false;
    }
}

bool ImgCutter::setOutputDirectory(QString dir){
    output_directory.setPath(dir);
    return output_directory.isReadable();
}

QString ImgCutter::getImageSample(){
    if(image_list.isEmpty()){
        emit error(tr("Image List Empty!"));
        return QString();
    }
    return image_list.first();
}

QList<QByteArray> ImgCutter::getTerminatedTask(){
    QList<QByteArray> data;
    if(!log_global.exists() || !QFile::exists("./data/log_rectmap")){
        return data;
    }

    log_global.open(QFile::ReadOnly);
    data = log_global.readAll().split('\n');
    log_global.close();

    if(data.length() != 2){
        log_global.remove();
        data.clear();
        return data;
    }

    return data;
}

void ImgCutter::start(int from){
    if(image_list.isEmpty()){
        emit error(tr("Image List Empty!"));
        return;
    }

    emit progressRange(0, image_list.length() - 1);

    QTextStream out;
    log_global.open(QFile::ReadWrite | QFile::Truncate);
    out.setDevice(&log_global);
    out << input_directory.absolutePath() << "\n" << output_directory.absolutePath();
    log_global.close();

    emit saveRectMap("./data/log_rectmap");

    cur_id = from;

    is_pausing = false;

    QThread::start();
}

void ImgCutter::restart(){
    if(image_list.isEmpty()){
        emit error(tr("Image List Empty!"));
        return;
    }

    emit progressRange(0, image_list.length() - 1);

    log_progress.open(QFile::ReadOnly);
    cur_id = log_progress.readAll().toInt();
    log_progress.close();

    is_pausing = false;

    QThread::start();
}

void ImgCutter::pause(){
    is_pausing = true;
}

void ImgCutter::cut(const QString &file_path){
    if(QFile::exists(file_path)){       
        if(rect_map == NULL || rect_map->isEmpty()){
            return;
        }

        QStringList all_subdir = output_directory.entryList(QDir::AllDirs);
        foreach(const QString &key, rect_map->keys()){
            if(!all_subdir.contains(key)){
                output_directory.mkdir(key);
            }
        }

        QMapIterator<QString, QRect> iter(*rect_map);
        while(iter.hasNext()){
            iter.next();
            QImage part = QImage(file_path).copy(iter.value());

            QString output_name;
            if(rename_style == Encoded){
                output_name = QFileInfo(file_path).completeBaseName();
                output_name.append('_');
                output_name.append(iter.key());
                output_name = Encryptor::encode(output_name);
            }else if(rename_style == Origin){
                output_name = QFileInfo(file_path).completeBaseName();
            }else{
                output_name = QString::number(cur_id);
            }

            QString path = QString("%1/%2/%3.jpg").arg(output_directory.absolutePath(), iter.key(), output_name);
            part.save(path);
        }
    }else{
        emit error(tr("File does not exist."));
    }
}

void ImgCutter::run(){
    while(cur_id < image_list.length()){
        while(is_pausing){
            sleep(1);
        }

        QString file = image_list.at(cur_id);
        if(cur_id % 10 == 0){
            log_progress.open(QFile::ReadWrite | QFile::Truncate);
            QTextStream out(&log_progress);
            out << cur_id;
            log_progress.close();
        }

        emit progressChanged(cur_id);
        cut(input_directory.absolutePath() + "/" + file);
        cur_id++;
    }

    log_global.remove();
    log_progress.remove();
}
